/**
 * @file   dictionary.h
 * @author wolfhead <wolfhead@wolfhead-laptop>
 * @date   Fri Oct 21 09:36:18 2011
 * 
 * @brief  
 * 
 * 
 */
#ifndef PROTOPLASM_DICTIONARY_H
#define PROTOPLASM_DICTIONARY_H


#include <map>
#include <vector>
#include <string>
#include "attribute.h"
#include "config.h"

namespace PP
{

class ParserFactory;

class Dictionary
{
public:
    enum
    {
        npos = (~0x00000000)
    };

    Dictionary(const DictionaryConfig& config);

    ~Dictionary();

    /**
     * Get the DictionaryConfig bound to this dictionary
     * @return DictionaryConfig
     */
    const DictionaryConfig& GetConfig() const;

    /**
     * GetAttribute 
     * Get Attribute By name, if the name does not exist return NULL
     * @return Attribute*
     */
    Attribute * GetAttribute(const std::string& name) const;

    /**
     * GetAttribute 
     * Get Attribute By Index, if the index does not exist return NULL
     * BUGBUG: is this nessecery?
     * @return Attribute*
     */
    Attribute * GetAttribute(size_t index) const;

    /**
     * GetOffset
     * 
     */
    size_t GetOffset(const std::string& name) const;

    /**
     * GetParser
     * 
     */
    Parser * GetParser(const std::string& name) const;


    /**
     * GetSize
     * Get total size in bytes
     */
    size_t GetSize() const;

    /**
     * GetIndex
     * Get index of a given key, npos when not exist
     */
    size_t GetIndex(const std::string& name) const;

    /**
     * AppendAttribute to this Dictionary
     * the life cycle of the attribute is maintained by this dictionary
     */
    int AppendAttribute(Attribute * pAttr);

    /**
     * Size 
     * Get Attribute Count int this dictionary
     */
    size_t Size() const;

    /**
     * Initialize
     * 
     */
    int Initialize(ParserFactory* pParserFactory);

    /**
     * ToString
     * 
     */
    std::string ToString() const;

private:

    typedef std::map<std::string/*name*/, Attribute *> AttrNameMap;
    typedef std::vector<Attribute *> AttrIndexMap;
    typedef std::map<std::string/*name*/, int> NameIndexMap;
    typedef std::map<std::string/*name*/, size_t> NameOffsetMap;

    DictionaryConfig config_;
    AttrNameMap attrNameMap_;
    AttrIndexMap attrIndexMap_;
    NameIndexMap nameIndexMap_;
    NameOffsetMap nameOffsetMap_;

    size_t dataLen_;
    
    Dictionary(const Dictionary&);
    Dictionary& operator= (const Dictionary&);
};

}

#endif

